﻿using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestListGenerator.Tests
{
    /// <summary>
    /// Common objects that are used by all the tests
    /// </summary>
    public class TestObjects
    {

        public const string TEST_SUBJECT_ASSEMBLY = @"TestListGenerator.Tests.TestSubject";
        public const string TEST_SUBJECT_CLASS_1 = "TestListGenerator.Tests.TestSubject.TestSubject1";
        public const string TEST_SUBJECT_CLASS_2 = "TestListGenerator.Tests.TestSubject.TestSubject2";
        public static Assembly TestSubjectAssembly;
        public static Dictionary<string, Type> TestSubjectExportedTypes;
        
        /// <summary>
        /// Instantiate the static objects
        /// </summary>
        static TestObjects()
        {
            TestObjects.TestSubjectAssembly = Assembly.Load(TEST_SUBJECT_ASSEMBLY);
            TestObjects.TestSubjectExportedTypes = new Dictionary<string, Type>();
            foreach (Type t in TestObjects.TestSubjectAssembly.GetExportedTypes())
            {
                TestObjects.TestSubjectExportedTypes[t.FullName] = t;
            }
        }
        #region Helper Routines
        /// <summary>
        /// Returns the Type class of the name passed in
        /// </summary>
        /// <param name="typeName">The full name of the type to retrieve</param>
        /// <returns>The Type for the full name passed in</returns>
        public static Type GetType(string typeName)
        {
            return TestObjects.TestSubjectExportedTypes[typeName];
        }

        /// <summary>
        /// Returns the MethodInfo for the method name passed in
        /// </summary>
        /// <param name="type">The type to search for the method</param>
        /// <param name="methodName">The method to return</param>
        /// <returns>The method specified by name</returns>
        public static MethodInfo GetMethod(string typeName, string methodName)
        {
            // Get the appropriate type            
            return GetMethod(GetType(typeName), methodName);
        }

        /// <summary>
        /// Returns the MethodInfo for the method name passed in
        /// </summary>
        /// <param name="type">The type to search for the method</param>
        /// <param name="methodName">The method to return</param>
        /// <returns>The method specified by name</returns>
        public static MethodInfo GetMethod(Type type, string methodName)
        {
            if (type == null)
            {
                throw new ArgumentNullException("The type you passed in was null");
            }
            MethodInfo mi = type.GetMethod(methodName);
            if (mi == null)
            {
                throw new ArgumentException("Unable to find " + methodName + " in " + type.FullName);
            }
            else
            {
                return mi;
            }
        }
        #endregion

    }
}
